home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 2.toast / pc / sample code / overview / dtscpluslibrary / sources / random.cp < prev    next >
Encoding:
Text File  |  2000-09-28  |  6.6 KB  |  267 lines

  1. /*
  2.     File:        Random.cp
  3.  
  4.     Contains:    TRandom is a stackbased utility class for random number generation.
  5.                  TRandom.cp contains the member function implementations for TRandom.
  6.  
  7.     Written by:     
  8.  
  9.     Copyright:    Copyright © 1991-1999 by Apple Computer, Inc., All Rights Reserved.
  10.  
  11.                 You may incorporate this Apple sample source code into your program(s) without
  12.                 restriction. This Apple sample source code has been provided "AS IS" and the
  13.                 responsibility for its operation is yours. You are not permitted to redistribute
  14.                 this Apple sample source code as "Apple sample source code" after having made
  15.                 changes. If you're going to re-distribute the source, we require that you make
  16.                 it clear in the source that the code was descended from Apple sample source
  17.                 code, but that you've made changes.
  18.  
  19.     Change History (most recent first):
  20.                 8/18/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  21.                 
  22.  
  23. */
  24. // Include files
  25. #ifndef _RANDOM_
  26. #include "Random.h"
  27. #endif
  28.  
  29.  
  30. // _________________________________________________________________________________________________________ //
  31. // TRandom class member function implementations
  32. //    CONSTRUCTORS & DESTRUCTORS
  33. #pragma segment Random
  34. TRandom::TRandom(ERandType theType,
  35.                  long theSeed,
  36.                  unsigned short low,
  37.                  unsigned short high)
  38. // Default constructor, most of the parameters have default values defined in the
  39. // header file (change if needed).
  40. {
  41.     if (theSeed == 1)                            // no seed value
  42.         this->ShuffleSeed();                    // no first value, random value
  43.     else
  44.         this->SetSeedValue(theSeed);            // programmer defined seed    
  45.  
  46.     this->fLow = low;                            // define the range
  47.     this->fHigh = high;
  48.     this->fRange = high - low;
  49.  
  50.     Boolean fState = this->IRandom(theType);    // initialize the object
  51. }
  52.  
  53.  
  54. #pragma segment Random
  55. TRandom::TRandom(const TRandom& other)
  56. // copy constructor, creates clones of the TRandom class (deep copy).
  57. {
  58.     register int x;
  59.  
  60.     // fill in the needed fields with values from the referenced object
  61.     this->fGenerator = other.fGenerator;
  62.     this->fAlgorithm = other.fAlgorithm;
  63.     this->fLow = other.fLow;
  64.     this->fHigh = other.fHigh;
  65.     this->fRange = other.fRange;
  66.     this->fSeed = other.fSeed;
  67.     this->fState = other.fState;
  68.     this->fPrevNum = other.fPrevNum;
  69.  
  70.     for (x = 0; x < kSHUFFLETABLE; x++)            // copy the values from array
  71.         this->fShuffleBuf[x] = other.fShuffleBuf[x];
  72. }
  73.  
  74.  
  75. #pragma segment Random
  76. TRandom& TRandom::operator=(const TRandom& other)
  77. // assignment operator, assign a TRandom class to another for quick cloning.
  78. {
  79.     register int x;
  80.  
  81.     // fill in the needed fields with values from the referenced object
  82.     this->fGenerator = other.fGenerator;
  83.     this->fAlgorithm = other.fAlgorithm;
  84.     this->fLow = other.fLow;
  85.     this->fHigh = other.fHigh;
  86.     this->fRange = other.fRange;
  87.     this->fSeed = other.fSeed;
  88.     this->fState = other.fState;
  89.     this->fPrevNum = other.fPrevNum;
  90.  
  91.     for (x = 0; x < kSHUFFLETABLE; x++)            // copy the values from array
  92.         this->fShuffleBuf[x] = other.fShuffleBuf[x];
  93.  
  94.     return *this;
  95. }
  96.  
  97.  
  98. #pragma segment Random
  99. TRandom::~TRandom()
  100. // Virtual destructor, we are not doing anything inside this one just now, note 
  101. // that virtual destructors should not be inlined.
  102. {
  103. }
  104.  
  105.  
  106. //    INITIATION ROUTINES
  107. #pragma segment Random
  108. Boolean TRandom::IRandom(ERandType theType)
  109. // We are using a special IRandom member function for initializing class fields to
  110. // known values. This is called from both the constructor, and when we switch the
  111. // internal random number algorithm.
  112. {
  113.     switch (theType)
  114.     {
  115.         case kMACOS:
  116.             qd.randSeed = this->GetSeedValue();
  117.             this->fGenerator = &TRandom::MacRandom;// quick init
  118.             this->fAlgorithm = kMACOS;
  119.             break;
  120.         case kSHUFFLE:
  121.             qd.randSeed = this->GetSeedValue();
  122.             this->fGenerator = &TRandom::ShuffleRandom;
  123.             this->fAlgorithm = kSHUFFLE;
  124.             this->InitShuffleRandom();
  125.             break;
  126.         case kPM:
  127.             this->fGenerator = &TRandom::ParkMiller;
  128.             this->fAlgorithm = kPM;
  129.             break;
  130.         default:
  131.             ASSERT(false, "\pProblems setting the algorithm for the random generator");
  132.             return false;                        // should never get here...
  133.     };
  134.     return true;
  135. }
  136.  
  137.  
  138. //    RANDOM GENERATOR ALGORITHMS/MEMBER FUNCTIONS
  139. #pragma segment Random
  140. unsigned short TRandom::MacRandom()
  141. // Macintosh Toolbox random number generator.
  142. {
  143.     register unsigned short temp;
  144.  
  145.     temp =
  146.           short(::Random());                    // scale to  0 - 65536
  147.     return (((temp * this->fRange) / k16BIT) + this->fLow);
  148. }
  149.  
  150.  
  151.  
  152.  
  153. #pragma segment Random
  154. unsigned short TRandom::ShuffleRandom()
  155. // Shuffle Random algorithm, uses an internal table for shuffling values for more
  156. // random distribution
  157. {
  158.     register unsigned short index;
  159.  
  160.     index = (this->fPrevNum * kSHUFFLETABLE) / k16BIT;
  161.     this->fPrevNum = this->fShuffleBuf[index];    // get random number from table
  162.     this->fShuffleBuf[index] = Random();        // new random table entry
  163.  
  164.     return (((this->fPrevNum * this->fRange) / k16BIT) + this->fLow);
  165. }
  166.  
  167.  
  168. #pragma segment Random
  169. TRandom& TRandom::InitShuffleRandom()
  170. // Used to initialize the Shuffle random algorithm
  171. {
  172.     register short i;
  173.  
  174.     for (i = 0; i < kSHUFFLETABLE; i++)
  175.         Random();                                // shuffle the random generator
  176.     for (i = 0; i < kSHUFFLETABLE; i++)
  177.         this->fShuffleBuf[i] = Random();        // fill the buffer
  178.  
  179.     this->fPrevNum = Random();                    // get first 'later' value
  180.     return *this;
  181. }
  182.  
  183.  
  184. #pragma segment Random
  185. unsigned short TRandom::ParkMiller()
  186. // CACM Oct 1988 Park& Miller algorithm.
  187. {
  188.     unsigned short high,
  189.      low;
  190.     register unsigned short temp;
  191.  
  192.     high =
  193.           short(this-> fSeed/ kPM3);
  194.     low =
  195.          short(this-> fSeed% kPM3);
  196.     temp = (kPM2 * low) - (kPM1 * high);
  197.  
  198.     if (temp > 0)
  199.         this->fSeed = temp;
  200.     else
  201.         this->fSeed = temp + kACM_MAX;
  202.  
  203.     return (((temp * this->fRange) / k16BIT) + this->fLow);
  204. }
  205.  
  206.  
  207. #pragma segment Random
  208. unsigned short TRandom::Next()
  209. // Iterate to next value.
  210. {
  211.     return (this->*fGenerator)();
  212. }
  213.  
  214.  
  215. #pragma segment Random
  216. TRandom& TRandom::ShuffleSeed()
  217. // Shuffle the current seed.
  218. {
  219.     this->fSeed = TickCount();
  220.     return *this;
  221. }
  222.  
  223.  
  224. // GET/SET FUNCTIONS
  225. #pragma segment Random
  226. TRandom& TRandom::SetRandomGenerator(TRandom::ERandType theType)
  227. // Select the random generator algorithm.
  228. {
  229.     this->IRandom(theType);
  230.     return *this;
  231. }
  232.  
  233.  
  234. #pragma segment Random
  235. long TRandom::GetSeedValue() const
  236. // Return current seed value.
  237. {
  238.     return this->fSeed;
  239. }
  240.  
  241.  
  242. #pragma segment Random
  243. TRandom& TRandom::SetSeedValue(const long theSeed)
  244. // Set current seed value
  245. {
  246.     this->fSeed = theSeed;
  247.     qd.randSeed = theSeed;
  248.     return *this;
  249. }
  250.  
  251.  
  252. #pragma segment Random
  253. TRandom::ERandType TRandom::GetAlgorithmType() const
  254. // Return algorithm type.
  255. {
  256.     return this->fAlgorithm;
  257. }
  258.  
  259.  
  260. // _________________________________________________________________________________________________________ //
  261.  
  262. /*    Change History (most recent last):
  263.   No        Init.    Date        Comment
  264.   1            khs        6/2/92        New file
  265.   2            khs        1/7/93        Cleanup
  266. */
  267.